#pragma once
#include "mysql.hpp"
#include "chat_session.hxx"
#include "chat_session-odb.hxx"
#include "mysql_chat_session_member.hpp"

class ChatSessionTable
{
public:
    using ptr = std::shared_ptr<ChatSessionTable>;
    ChatSessionTable(const std::shared_ptr<odb::core::database> &db) : _db(db) {}
    ~ChatSessionTable() {}

    bool insert(ChatSession &cs)
    {
        try
        {
            odb::transaction trans(_db->begin());
            _db->persist(cs);
            trans.commit();
        }
        catch (const std::exception &e)
        {
            LOG_ERROR("新增会话失败 {}-{}")
            return false;
        }
        return true;
    }

    bool remove(const std::string &ssid)
    {
        try
        {
            odb::transaction trans(_db->begin());
            typedef odb::query<ChatSession> query;
            _db->erase_query<ChatSession>(query::chat_session_id == ssid);

            // 如果会话删除了，那么对应的会话成员表中也要对应删除
            typedef odb::query<ChatSessionMember> mquery;
            _db->erase_query<ChatSessionMember>(mquery::session_id == ssid);
            trans.commit();
        }
        catch (std::exception &e)
        {
            LOG_ERROR("删除会话失败 {}:{}！", ssid, e.what());
            return false;
        }
        return true;
    }

    bool remove(const std::string &uid, const std::string &pid)
    {
        // 单聊会话的删除，-- 根据单聊会话的两个成员
        try
        {
            odb::transaction trans(_db->begin());
            typedef odb::query<SingleChatSession> query;
            typedef odb::result<SingleChatSession> result;
            auto res = _db->query_one<SingleChatSession>(
                query::csm1::user_id == uid &&
                query::csm2::user_id == pid &&
                query::css::chat_session_type == ChatSessionType::SINGLE);

            std::string cssid = res->chat_session_id;
            typedef odb::query<ChatSession> cquery;
            _db->erase_query<ChatSession>(cquery::chat_session_id == cssid);

            typedef odb::query<ChatSessionMember> mquery;
            _db->erase_query<ChatSessionMember>(mquery::session_id == cssid);
            trans.commit();
        }
        catch (const std::exception &e)
        {
            LOG_ERROR("删除会话失败 {}-{}:{}！", uid, pid, e.what());
            return false;
        }
        return true;
    }

    std::shared_ptr<ChatSession> select(const std::string &ssid)
    {
        std::shared_ptr<ChatSession> res;
        try
        {
            odb::transaction trans(_db->begin());
            typedef odb::query<ChatSession> query;
            res.reset(_db->query_one<ChatSession>(query::chat_session_id == ssid));
            trans.commit();
        }
        catch (const std::exception &e)
        {
            LOG_ERROR("通过会话ID获取会话信息失败 {}:{}！", ssid, e.what());
        }
        return res;
    }

    std::vector<SingleChatSession> singleChatSession(const std::string &uid)
    {
        std::vector<SingleChatSession> res;
        try
        {
            odb::transaction trans(_db->begin());
            typedef odb::query<SingleChatSession> query;
            typedef odb::result<SingleChatSession> result;
            // 当前的uid是被申请的用户ID
            result r(_db->query<SingleChatSession>(
                query::css::chat_session_type == ChatSessionType::SINGLE &&
                query::csm1::user_id == uid &&
                query::csm2::user_id != query::csm1::user_id));

            for (result::iterator it(r.begin()); it != r.end(); it++)
            {
                res.push_back(*it);
            }

            trans.commit();
        }
        catch (const std::exception &e)
        {
            LOG_ERROR("获取用户{} 的单聊会话失败", uid, e.what());
        }

        return res;
    }

    std::vector<GroupChatSession> groupChatSession(const std::string &uid)
    {
        std::vector<GroupChatSession> res;
        try
        {
            odb::transaction trans(_db->begin());
            typedef odb::query<GroupChatSession> query;
            typedef odb::result<GroupChatSession> result;
            result r(_db->query<GroupChatSession>(
                query::css::chat_session_type == ChatSessionType::GROUP &&
                query::csm1::user_id == uid));

            for (result::iterator i(r.begin()); i != r.end(); ++i)
            {
                res.push_back(*i);
            }

            trans.commit();
        }
        catch (const std::exception &e)
        {
            LOG_ERROR("获取用户{} 群聊的会话失败", uid, e.what());
        }

        return res;
    }

private:
    std::shared_ptr<odb::core::database> _db;
};